public class Node
{
	Board state;
	Node parentNode;
	Action action;
	int pathCost;
	int depth;
	int heuristic;
	int heuristiCost; // f(n) = g + h
	
	public Node(Board board)
	{
		state = board;
		parentNode = null;
		action = null;
		pathCost = 0;
		depth = 0;
	}
	
	public Node(Board board, int h)
	{
		state = board;
		parentNode = null;
		action = null;
		pathCost = 0;
		depth = 0;
		setHeuristic(h);
	}
	
	public Node(Node parent,Action action, int h)
	{
		try
		{
			state = Board.generateBoard(parent.state,action);
			this.action = action;
		}
		catch(Exception e)
		{
			System.out.println("Node creation error");
		}
		
		parentNode = parent;
		pathCost = parent.pathCost +1;
		depth = parent.depth +1;
		
		setHeuristic(h);
	}
	
	public Node(Node parent,Action action)
	{
		try
		{
			state = Board.generateBoard(parent.state,action);
			this.action = action;
		}
		catch(Exception e)
		{
			System.out.println("Node creation error");
		}
		
		parentNode = parent;
		pathCost = parent.pathCost +1;
		depth = parent.depth +1;
	}
	
	void setHeuristic(int x)
	{
		this.heuristic = 0;
		
		if(x==0) // use the first heuristic function (distance between the mouse and the edge of the board)
		{
			for(int i = 5;i >= 0;i--)
			{
				if(this.state.board[2][i] == null || !(this.state.getBlock(this.state.board[2][i]) instanceof Mouse))
				{
					this.heuristic ++;
				}
				else
				{
					this.heuristiCost = this.heuristic + this.depth;
					break;
				}
			}
		}
		else // use the second heuristic function (like the first heuristic but is more precise as it counts the blocks blocking the way)
		{
			for(int i = 5;i >= 0;i--)
			{
				if(this.state.board[2][i] == null)
				{
					this.heuristic ++;
				}
				else if(!(this.state.getBlock(this.state.board[2][i]) instanceof Mouse))
				{
					this.heuristic += 2;
				}
				else
				{
					this.heuristiCost = this.heuristic + this.depth;
					break;
				}
			}
		}
	}
	
}
